(function (window,avalon) {
    var requestAnimationFrame = (function() { //requestAnimationFrame 兼容
        return window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            function(callback) {
                window.setTimeout(callback, 25)
            }
    })()

    var Tween = { //线性以及二次方的缓动
        linear: function(t, b, c, d) {
            return c * t / d + b
        },
        easeIn: function(t, b, c, d) {
            return c * (t /= d) * t + b
        },
        easeOut: function(t, b, c, d) {
            return -c * (t /= d) * (t - 2) + b
        },
        easeInOut: function(t, b, c, d) {
            if ((t /= d / 2) < 1) return c / 2 * t * t + b
            return -c / 2 * ((--t) * (t - 2) - 1) + b
        }
    }
    
    var LazyLoading = avalon.LazyLoading = function () {}
    var lazyElementArr = []
    var scTop = 0
    LazyLoading.prototype = {
        options:{
            width:"", // 懒加载占位宽度，可通过设置元素的data-lazyload-width修改
            height:"", //懒加载占位高度，可通过设置元素的data-lazyload-height修改
            preLoadSrc: "./loadingimg/loading1.gif", // 预加载图片路径
            delay: 1000, //延迟加载时间（毫秒）。也可以设置元素的data-lazyload-itemdelay，替代默认值
            effect: "none", //预加载效果 "none"-无效果 / "fadeIn"-渐入效果 / "slideX"-由左向右滑动 / "slideY"-由上向下滑动，建议在图片加载中使用。也可以设置元素的data-lazyload-itemeffect，替代默认值
            easing: "easeInOut", //  动画效果的缓动函数
            slideDistance: 300 //effect-slide模式的滑动长度。也可以设置元素的data-lazyload-distance，替代默认值
        },
        normalGetElementByAttr:function(attrName,useName){
            var all = Object.prototype.hasOwnProperty.call(document, "all")?document.all:document.getElementsByTagName('*');
            var elements = new Array();
            for ( var e = 0; e <all.length; e ++ ) {
                if (all[e].getAttribute(attrName) == useName ) {
                    elements.push(all[e])
                }
            }
            return elements;
        },
        //记录元素替换背景
        lazyload: function() {
            //获取lazyload元素
            var lazyElements = this.normalGetElementByAttr('ms-lazyload','true')
            if(!lazyElements){
                return
            }
            for(var i=0,j=lazyElements.length;i<j;i++){
                var element = lazyElements[i];
                element.removeAttribute("ms-lazyload")
                //加载占位图片为1像素透明图
                if (element.tagName === "IMG") {
                    element.setAttribute('data-lazyload-original',element.src)
                    if(!element.hasAttribute('width') && !element.hasAttribute('height')){
                        element.setAttribute('width',element.clientWidth)
                        element.setAttribute('height',element.clientHeight)
                        element.setAttribute('nosize',true)
                    }
                    element.src = "./loadingimg/placeholder.png"
                    //loading占位
                        element.originalCssBackground = avalon.css(element, "background-image") //记录原背景CSS
                        element.style.background = "url(" + this.options.preLoadSrc + ") no-repeat center center" //设置load旋转图为背景
                        this._renderImg(element, this.options.preLoadSrc, false, false)
                        lazyElementArr.push(element) 
                }else{

                    var imgeles = element.getElementsByTagName('IMG')
                    for(var p=0,q=imgeles.length;p<q;p++){
                        if(imgeles[p]){
                            imgeles[p].setAttribute('data-lazyload-original',imgeles[p].src)
                            imgeles[p].src = "js/images/placeholder.png"
                            //loading占位
                            imgeles[p].originalCssBackground = avalon.css(imgeles[p], "background-image") //记录原背景CSS
                            imgeles[p].style.background = "url(" + this.options.preLoadSrc + ") no-repeat center center" //设置load旋转图为背景
                            this._renderImg(imgeles[p], this.options.preLoadSrc, false, false)
                            lazyElementArr.push(element)
                        }
                    }
                }
                
            }
            this.bindEvent();
        },
        _renderImg: function(ele, src, isloadingOriginal, needResize, tempImgItem) {
            var _this = this
            var placeholderImg = new Image(),
            effect = ele.getAttribute("data-lazyload-itemeffect") !== null ? ele.getAttribute("data-lazyload-itemeffect") : this.options.effect
            placeholderImg.onload = function() {
                _this.options.width = ele.getAttribute("data-lazyload-width") || _this.options.width
                _this.options.height = ele.getAttribute("data-lazyload-height") || _this.options.height

                    if(_this.options.width !== "" || _this.options.height !== ""){
                        if(options.width !== ""){
                            avalon.css(ele, "width", _this.options.width)
                            ele.preLoadSetSize = true;
                        }
                        if(_this.options.height !== ""){
                            avalon.css(ele, "height", _this.options.height)
                            ele.preLoadSetSize = true;
                        }
                        //置空控制重复设置
                        _this.options.width = ""
                        _this.options.height = ""
                    }

                    //CSS设置了DOM宽高时采用originalSize,否则采用src的宽高
                    else if (ele.width <= 1 || ele.height <= 1 || typeof ele.width === "undefined" || typeof ele.height === "undefined" || needResize) {
                        if (needResize) {
                            avalon.css(ele, "width", "auto")
                            avalon.css(ele, "height", "auto")
                        } 
                        if (needResize) { //根据originalSrc重新设定尺寸结束以后删除preLoadSetSize属性
                            try { //ie不支持
                                delete ele.preLoadSetSize
                            } catch (e) {}
                        } else { //ele尺寸未设置，需要根据originalSrc重新设定尺寸
                            ele.preLoadSetSize = true
                        }
                    }
                    //加载原图 / DOM
                    if (isloadingOriginal) {
                        ele.src = src //大小确定后加载原图
                        if(ele.hasAttribute('nosize')){
                            ele.removeAttribute('width')
                            ele.removeAttribute('height')
                        }
                    }

                    //Effect 模式
                    if ((effect === "fadeIn" || effect === "slideY" || effect === "slideX") && isloadingOriginal) {
                        _this._EffectStart(ele, effect)
                    }
                }
                placeholderImg.src = src    
        },
        _delayload:function(){
            for (var i = 0, len = lazyElementArr.length; i < len; i++) {
                //有可能无法根据IMG标签判断位置,因此监听其父级中可以判断位置的标签,需要添加ms-lazyload属性
                var positionWatchEle = lazyElementArr[i],
                    eleTop = positionWatchEle.offsetTop,
                    eleHeight = positionWatchEle.offsetHeight,
                    winHeight = document.compatMode === "BackCompat" ? document.body.clientHeight : document.documentElement.clientHeight
                if(positionWatchEle.tagName != 'IMG'){
                    var imgItems = positionWatchEle.getElementsByTagName('IMG')
                    for(var p=0,q=imgItems.length;p<q;p++){
                        this._laodWatching(imgItems[p],eleTop,eleHeight,winHeight)
                    }
                }else{
                    this._laodWatching(positionWatchEle,eleTop,eleHeight,winHeight)
                }
            }
        },
        _laodWatching:function(ele,eleTop,eleHeight,winHeight){
            var _self = this
            //加载正确的图片(originalSrc),条件是屏幕范围内并且要防止重复设置
            if (scTop+winHeight>=eleTop + eleHeight  && !ele.lazyloaded) {
                //延迟加载
                setTimeout((function(ele, originalSrc) {
                    return function() {
                        _self._renderImg(ele, originalSrc, true, ele.preLoadSetSize)

                        //加载完成
                        ele.lazyloaded = true
                        ele.removeAttribute("data-lazyload-original")
                        avalon.css(ele, "background-image", ele.originalCssBackground)
                        try { //ie不支持
                            delete ele.originalCssBackground
                        } catch (e) {}
                    }
                })(ele, ele.getAttribute("data-lazyload-original")), ele.getAttribute("data-lazyload-itemdelay") || this.options.delay)
            }
        },
        _EffectStart:function(ele, effect){
            var _this = this
            if (ele.animated) {
                return
            }
            var currentTime = 0,
                distance = ele.getAttribute("data-lazyload-distance") || this.options.slideDistance,
                startpos = effect === "fadeIn" ? 0 : -distance,
                duringDistance = effect === "fadeIn" ? 1 : distance,
                duringTime = 20,
                cssName
            if (effect === "fadeIn") {
                cssName = "opacity"
            } else {
                cssName = effect === "slideY" ? "margin-top" : "margin-left"
            }
            var _EffectGo = function() {
                cssValue = Tween[_this.options.easing](currentTime, startpos, duringDistance, duringTime) //移动
                if (currentTime < duringTime) {
                    avalon.css(ele, cssName, cssValue)
                    currentTime += 1
                    requestAnimationFrame(_EffectGo)
                }
            }
            ele.animated = true
            _EffectGo()
        },
        bindEvent: function() {
            var _this = this
            avalon.bind(window, "load", function() {
                scTop = document.body.scrollTop;
                _this._delayload()
            });
            avalon.bind(window,"scroll",function(){
                scTop = document.compatMode === "BackCompat" ? document.body.scrollTop : document.documentElement.scrollTop
                if(scTop === 0){ //修正chrome下取不到的問題
                    scTop = document.body.scrollTop;
                }
                _this._delayload()
            });
        },
        init: function(opt) {
            if(opt){
                this.options = avalon.mix(this.options,opt)
            }
            this.lazyload();
        }
    }
    window.LazyLoading = window.LazyLoading || LazyLoading
})(window,avalon)
